package pkg

import (
	"github.com/gin-gonic/gin"
	"github.com/samber/do"
	"github.com/spf13/afero"
	"gitlab.local/DO-module/new-filemanage-module/src"
	"gitlab.local/DO-module/new-filemanage-module/src/controller"
	"gitlab.local/DO-module/new-filemanage-module/src/core/directory"
	"gitlab.local/DO-module/new-filemanage-module/src/core/fileoperate"
	"gitlab.local/DO-module/new-filemanage-module/src/core/httplogger"
	"gitlab.local/DO-module/new-filemanage-module/src/core/redisdb"
	"gitlab.local/DO-module/new-filemanage-module/src/core/sqlitedb"
	"gitlab.local/DO-module/new-filemanage-module/src/service/filesystem"
	"gitlab.local/DO-module/new-filemanage-module/src/service/folder"
	"gitlab.local/DO-module/new-filemanage-module/src/service/sharefolder"
	"gitlab.local/DO-module/new-filemanage-module/src/service/taskhook"
	"gitlab.local/TerraMaster/tos-modules"
	"gitlab.local/TerraMaster/tos-modules/database"
	"gitlab.local/TerraMaster/tos-modules/service/disk"
	"gitlab.local/golibrary/sysconfig"

	acl2 "gitlab.local/TerraMaster/tos-modules/core/acl"
	directory2 "gitlab.local/TerraMaster/tos-modules/directory"

	"gitlab.local/DO-module/new-filemanage-module/src/core/middleware"
	"gitlab.local/DO-module/new-filemanage-module/src/core/network"
	"gitlab.local/DO-module/new-filemanage-module/src/core/nginx"
	"gitlab.local/DO-module/new-filemanage-module/src/service/user"
	fileoperate2 "gitlab.local/TerraMaster/tos-modules/fileoperate"
	folder2 "gitlab.local/TerraMaster/tos-modules/folder"
	sharefolder2 "gitlab.local/TerraMaster/tos-modules/service/sharefolder"
	"gitlab.local/TerraMaster/tos-modules/servicectl"
	"gitlab.local/TerraMaster/tos-modules/tnasonline"
	"log"
)

// InitModule :
func InitModule(_injector *do.Injector) {
	initFileSystem(_injector)
}

var (
	folderObj       *folder.Folder
	aclHandle       acl2.FolderAttrService
	fOptHandle      fileoperate2.Getter
	shareFolderObj  sharefolder2.Service
	directoryHandle directory2.FolderService
	nginxHandle     nginx.PortGetter
	personHandle    user.UserService
	tnasOnline      tnasonline.Ctl
	networkHandle   network.Networkset
)

func initFileSystem(_injector *do.Injector) {
	databaseObj, err := sqlitedb.New()
	if err != nil {
		log.Fatalln(err)
	}

	redisDB, err := redisdb.New()
	if err != nil {
		log.Fatalln(err)
	}
	ao := afero.NewOsFs()
	sysConfig := sysconfig.New()

	networkHandle = network.New(sysConfig)
	// nginx
	nginxHandle = nginx.New()
	//acl
	//aclHandle = acl2.NewServiceAcl(databaseObj)

	//目录
	directoryHandle = directory.New(databaseObj)

	hookService := taskhook.New(sysConfig)

	//用户

	//文件操作
	tos_modules.DoProvide[fileoperate2.Getter](_injector, func(injector *do.Injector) (fileoperate2.Getter, error) {
		aclHandle = do.MustInvoke[acl2.FolderAttrService](injector)
		personHandle = user.New(databaseObj, sysConfig, directoryHandle, aclHandle)
		fOptHandle = fileoperate.New(databaseObj, aclHandle, personHandle, ao)
		return fOptHandle, nil
	})

	//文件管理
	middlewareHandle := middleware.New(databaseObj, ao, redisDB, hookService, aclHandle)
	tos_modules.DoProvide[sharefolder2.Service](_injector, func(injector *do.Injector) (sharefolder2.Service, error) {
		serviceHandle := do.MustInvoke[servicectl.Ctl](injector)
		databaseHandle := do.MustInvoke[database.DbGetter](injector)
		diskHandle := do.MustInvoke[disk.Getter](injector)
		folderObj = src.NewFolderHandle(databaseObj, fOptHandle, aclHandle)
		shareFolderObj = sharefolder.New(directoryHandle, personHandle, aclHandle, diskHandle, databaseHandle, serviceHandle, fOptHandle, folderObj)

		return shareFolderObj, nil
	})

	tos_modules.DoProvide[directory2.FolderService](_injector, func(injector *do.Injector) (directory2.FolderService, error) {
		directoryObj := directory.New(databaseObj)
		return directoryObj, nil
	})

	tos_modules.DoProvide[folder2.FoldersService](_injector, func(injector *do.Injector) (folder2.FoldersService, error) {
		//文件夹
		engine := do.MustInvoke[*gin.Engine](injector)
		tnasOnline = do.MustInvoke[tnasonline.Ctl](injector)
		fs := filesystem.GetInstance(databaseObj, tnasOnline, fOptHandle, aclHandle, nginxHandle, networkHandle, middlewareHandle)
		src.HandleController(engine, middlewareHandle, fOptHandle, aclHandle, fs, folderObj)
		httpServiceHandle := httplogger.New()
		new(controller.ShareFolder).Router(httpServiceHandle, engine, middlewareHandle, shareFolderObj, folderObj)

		return folderObj, nil
	})

}
